/**
 * kl yy-ds @2021
 */
package com.cxps.server.menu.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cxps.cloud.base.MyTree;
import com.cxps.cloud.base.Option;
import com.cxps.cloud.enums.DataStatus;
import com.cxps.cloud.message.MyPage;
import com.cxps.cloud.utils.DateUtil;
import com.cxps.cloud.utils.IdUtils;
import com.cxps.server.menu.domain.MenuEntity;
import com.cxps.server.menu.domain.MenuForm;
import com.cxps.server.menu.domain.MenuQuery;
import com.cxps.server.menu.domain.MenuVo;
import com.cxps.server.menu.mapper.MenuMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 菜单业务逻辑层
 *
 * @author YouCai.Liu
 * @since 2021/10/12 10:29
 * ...
 */
@Service
public class MenuService {

    @Autowired
    private MenuMapper menuMapper;

    /**
     * 菜单列表
     *
     * @param query
     */
    public Page getMenuList(MenuQuery query) {
        // 创建 MP 分页对象
        Page<MenuEntity> page = new Page<>(query.getCurrent(), query.getSize());

        // 构建查询条件
        QueryWrapper<MenuEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("sort_num");
        queryWrapper.eq("status", DataStatus.ON_LINE.getCode());
        // 菜单名
        if (StringUtils.isNotBlank(query.getMenuName())) {
            queryWrapper.like("menu_name", query.getMenuName());
        }
        // 菜单类型
        if (StringUtils.isNotBlank(query.getMenuType())) {
            queryWrapper.eq("menu_type", query.getMenuType());
        }

        // 执行查询
        IPage<MenuEntity> result = menuMapper.selectPage(page, queryWrapper);
        // 获取结果数据
        List<MenuEntity> entityList = result.getRecords();
        // 转换处理
        List<MenuVo> voList = new ArrayList<>();
        if (null != entityList && !entityList.isEmpty()) {
            for (MenuEntity entity : entityList) {
                MenuVo vo = new MenuVo();
                BeanUtils.copyProperties(entity, vo);

                vo.setUpdateTime(DateUtil.formatDate(entity.getUpdateTime()));

                voList.add(vo);
            }
        }
        Page<MenuVo> resultPage = new Page<>(query.getCurrent(), query.getSize());
        BeanUtils.copyProperties(result, resultPage);
        // 设置返回对象数据
        resultPage.setRecords(voList);

        return resultPage;
    }

    /**
     * 根据菜单ID查询数据
     *
     * @param id
     * @return
     */
    public MenuVo getMenuById(String id) {
        MenuEntity entity = menuMapper.selectById(id);
        if (null == entity) {
            return null;
        }
        MenuVo vo = new MenuVo();
        BeanUtils.copyProperties(entity, vo);
        // 转换
        if (null != entity.getUpdateTime()) {
            vo.setUpdateTime(DateUtil.formatDate(entity.getUpdateTime()));
        }

        return vo;
    }

    /**
     * 添加菜单
     *
     * @param form
     */
    public void addMenu(MenuForm form) {
        MenuEntity entity = new MenuEntity();
        BeanUtils.copyProperties(form, entity);
        entity.preInsert();
        entity.setId(IdUtils.generateId());
        menuMapper.insert(entity);
    }

    /**
     * 修改菜单
     *
     * @param form
     */
    public void updateMenu(MenuForm form) {
        MenuEntity entity = new MenuEntity();
        BeanUtils.copyProperties(form, entity);
        entity.preUpdate();
        menuMapper.updateById(entity);
    }

    /**
     * 根据菜单ID删除单个数据 (逻辑删除，修改数据状态 00)
     *
     * @param id
     */
    public void delMenuById(String id) {
        MenuEntity entity = new MenuEntity();
        entity.preUpdate();
        entity.setId(id);
        entity.setStatus(DataStatus.OFF_LINE.getCode());
        menuMapper.updateById(entity);
    }

    /**
     * 根据菜单ID删除多个数据 (逻辑删除，修改数据状态 00)
     *
     * @param ids
     */
    public void delMenuByIds(String[] ids) {
        for (String id : ids) {
            MenuEntity entity = new MenuEntity();
            entity.preUpdate();
            entity.setId(id);
            entity.setStatus(DataStatus.OFF_LINE.getCode());
            menuMapper.updateById(entity);
        }
        menuMapper.deleteMenuByIds(ids, "1", new Date());
    }

    /**
     * 获取上级菜单
     *
     * @return
     */
    public List<Option> getParentMenu() {
        List<Option> list = new ArrayList<>();
        QueryWrapper<MenuEntity> qw = new QueryWrapper<>();
        qw.select("id", "menu_name");
        qw.eq("status", DataStatus.ON_LINE.getCode());
        qw.eq("menu_type", "0");
        qw.orderByDesc("menu_name");
        List<MenuEntity> menus = menuMapper.selectList(qw);
        for (MenuEntity entity : menus) {
            list.add(new Option(entity.getId(), entity.getMenuName()));
        }
        return list;
    }

    /**
     * 获取树形结构菜单数据
     *
     * @return
     */
    public List<MyTree> getMenuTree() {

        // 查询所有菜单
        QueryWrapper<MenuEntity> qw = new QueryWrapper<>();
        qw.orderByAsc("sort_num");
        qw.eq("status", DataStatus.ON_LINE.getCode());
        List<MenuEntity> menuEntityList = menuMapper.selectList(qw);
        if (null == menuEntityList || menuEntityList.isEmpty()) {
            return null;
        }

        // 转成树形结构对象
        List<MyTree> myTreeList = new ArrayList<>();
        // 得到顶级父菜单
        List<MyTree> parentList = new ArrayList<>();
        for (MenuEntity entity : menuEntityList) {
            MyTree myTree = new MyTree(entity.getId(), entity.getPid(), entity.getMenuName());
            myTreeList.add(myTree);
            // -1是顶级父菜单ID
            if ("-1".equals(entity.getPid())) {
                parentList.add(myTree);
            }
        }

        List<MyTree> result = new ArrayList<>();

        // 遍历顶级父菜单集合，递归查找子节点数据
        for (MyTree parent : parentList) {
            result.add(buildTree(parent, myTreeList));
        }

        return result;
    }

    /**
     * 递归构建树形结构数据
     *
     * @param parentMenu  父节点数据
     * @param allMenuList 所有数据
     * @return
     */
    private MyTree buildTree(MyTree parentMenu, List<MyTree> allMenuList) {

        // 父节点子数据
        List<MyTree> children = new ArrayList<>();

        // 遍历所有的菜单数据，如果当前的数据PID = 父节点数据的ID，则是子节点
        for (MyTree myTree : allMenuList) {
            // 当前节点数据PID = 父节点数据的ID
            if (myTree.getPid().equals(parentMenu.getId())) {
                children.add(myTree);
                // 调自己，继续往下找
                buildTree(myTree, allMenuList);
            }
        }
        parentMenu.setChildren(children);
        return parentMenu;
    }

    /**
     * 查询所有的权限集合
     */
    public List<String> getAllMenu() {

        QueryWrapper<MenuEntity> qw = new QueryWrapper<>();
        qw.eq("status", "50");
        qw.select("menu_perm");
        List<MenuEntity> menuEntityList = menuMapper.selectList(qw);

        // 所有菜单权限标识集合
        List<String> menuPerms = new ArrayList<>();
        for (MenuEntity entity : menuEntityList) {
            menuPerms.add(entity.getMenuPerm());
        }
        return menuPerms;
    }
}
